#include "comm.hpp"
#include "fifo.hpp"

int main()
{

    // 1.客户端获取key值
    key_t key = GetShmKey();
    cout << "key=" << ToHex(key) << endl;
    // sleep(2);

    // 2.获取共享内存
    int shmid = GetShm(key, defaultsize);
    cout << "shmid: " << shmid << endl;
    // sleep(2);
    //  3.将共享内存与进程进行关联(构建页表映射关系)
    char *addr = (char *)ShmAttach(shmid);
    cout << "Attach shm success, addr: " << ToHex((uint64_t)addr) << endl;
    // sleep(15);
    

    //增加协调机制
    //客户端以写方式打开管道文件
    Sync syn;
    syn.OpenWrite();

    // 4.建立映射关系之后,客户端与服务端可以进行进程间通信
    // 客户端向共享内存写入数据,服务端从共享内存读取数据
    memset(addr, 0, defaultsize);
    for (char ch = 'A'; ch <= 'Z'; ch++)
    {
        // 客户端直接向shmat()函数返回的起始地址addr写入数据
        addr[ch - 'A'] = ch;
        sleep(1);
        //客户端写入结束,唤醒服务端
        syn.WakeUp();
    }
    // 现象:服务端运行后,即使客户端未写入任何数据,服务端依然会从共享内存中读取数据
    // 共享内存不提供进程间协同的任何机制,需要用户实现共享内存的同步机制

    // 客户端向共享内存中写入数据,写入结束时,通知服务端进行读取
    // 客户端向共享内存中写入数据,没有写入结束时,通知服务端进行等待
    // 通过管道实现上述机制(服务端创建管道文件)

    // 5.将共享内存与进程进行去关联(消除页表映射关系)(进程退出时,页表、进程地址空间均会销毁,也可以将共享内存与进程进行去关联)
    ShmDetach(addr);
    cout << "detach shm success, addr: " << ToHex((uint64_t)addr) << endl;
    // sleep(10);

    return 0;
}